package com.tencent.txcc.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.tencent.txcc.constants.RedisCourseTypeContants;
import com.tencent.txcc.domain.CourseType;
import com.tencent.txcc.dto.CrumbVo;
import com.tencent.txcc.mapper.CourseTypeMapper;
import com.tencent.txcc.service.ICourseTypeService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author director
 * @since 2022-10-07
 */

@Service
@Slf4j
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    /**
     * 获取课程分类树数据
     * @return 循环深度最大比如有1000条数据时那么就是1000*1000
     */
//    @Override
//    public List<CourseType> treeData() {
//        // 1.查询所有分类数据
//        List<CourseType> courseTypes = selectList(null);
//        // 2.遍历查询到的集合数据
//        List<CourseType> treeData = new ArrayList<>();
//        courseTypes.forEach(e->{
//            if (e.getPid() != null && e.getPid().intValue() == 0){ // 如果等于0，那么意味着他是顶级父类
//                treeData.add(e);
//            }else { // 有父类，需要找到自己的父亲
//                for (CourseType parent : courseTypes) {
//                    // 找到自己的父亲
//                    if (parent.getId().intValue() == e.getPid().intValue()){
//                        // 把自己放入到父亲中的chileren集合中
//                        parent.getChildren().add(e);
//                        // 当找到自己父亲时，没有继续循环的必要，因为我们必然只有一个爹
//                        break;
//                    }
//                }
//            }
//        });
//
//        return treeData;
//    }



    @Override // courseType::treeData   value：方法返回什么redis中存什么
    @Cacheable(cacheNames = RedisCourseTypeContants.COURSE_TYPE_TREE_DATA_CACHE_CACHENAMES, key = RedisCourseTypeContants.COURSE_TYPE_TREE_DATA_CACHE_KEY)
    public List<CourseType> treeData() {
        return tree();
    }





    @Override
    public List<CrumbVo> crumbs(Long courseTypeId) {
        // 通过传入的courseTypeId找到courseType
        CourseType courseType = selectById(courseTypeId);
        // 获取当前对象的path
        String path = courseType.getPath();
        // 将path分割
        String[] split = path.split("\\.");

        // 创建一个返回的集合
        ArrayList<CrumbVo> crumbVos = new ArrayList<>();

        // 遍历split中的每一个值，返回当前类型和同级类型
        for (String s : split) {
            // 创建一个返回对象
            CrumbVo crumbVo = new CrumbVo();
            // 通过遍历出来的courseTypeId找到他所对应的courseType
            CourseType thisCourseType = selectById(s);
            // 将查询出来的thisCourseType保存在crumbVo
            crumbVo.setOwnerProductType(thisCourseType);


            Wrapper<CourseType> wrapper = new EntityWrapper<>();
            wrapper.eq("pid", thisCourseType.getPid());
            List<CourseType> courseTypes = selectList(wrapper);
            crumbVo.setOtherProductTypes(courseTypes);

            crumbVos.add(crumbVo);
        }


        return crumbVos;
    }






    private List<CourseType> tree() {
        // 1.查询所有分类数据
        List<CourseType> courseTypes = selectList(null);
        // 将集合转换为map <courseType.getId()> <CourseType::getId(), courseType->courseType>
        Map<Long, CourseType> courseTypeMap = courseTypes.stream().collect(Collectors.toMap(CourseType::getId, courseType -> courseType));

//        HashMap<Long, CourseType> longCourseTypeHashMap = new HashMap<>();
//        for (CourseType courseType : courseTypes) {
//            longCourseTypeHashMap.put(courseType.getId(), courseType);
//        }

        // 2.遍历查询到的集合数据
        List<CourseType> treeData = new ArrayList<>();
        courseTypes.forEach(e->{
            if (e.getPid() != null && e.getPid().intValue() == 0){ // 如果等于0，那么意味着他是顶级父类
                treeData.add(e);
            }else { // 有父类，需要找到自己的父亲
                CourseType courseType = courseTypeMap.get(e.getPid());
                if (courseType != null){ // 万一儿子的pid是脏数据，那么就拿不到父亲
                    courseType.getChildren().add(e);
                }
            }
        });
        //redisTemplate.opsForValue().set(RedisCourseTypeConstants.COURSE_TYPE_TREE_DATA, treeData);

        return treeData;
    }

    @Override
    @CacheEvict(cacheNames = RedisCourseTypeContants.COURSE_TYPE_TREE_DATA_CACHE_CACHENAMES, key = RedisCourseTypeContants.COURSE_TYPE_TREE_DATA_CACHE_KEY)
    public boolean insert(CourseType entity) {
        return super.insert(entity);
    }


    @Override
    @CacheEvict(cacheNames = RedisCourseTypeContants.COURSE_TYPE_TREE_DATA_CACHE_CACHENAMES, key = RedisCourseTypeContants.COURSE_TYPE_TREE_DATA_CACHE_KEY)
    public boolean updateById(CourseType entity) {
        return super.updateById(entity);
    }

    @Override
    @CacheEvict(cacheNames = RedisCourseTypeContants.COURSE_TYPE_TREE_DATA_CACHE_CACHENAMES, key = RedisCourseTypeContants.COURSE_TYPE_TREE_DATA_CACHE_KEY)
    public boolean deleteById(Serializable id) {
        return super.deleteById(id);
    }
}
